#include "VolumeUtil.h"
#include "OCMain/Log.h"

namespace OCPP{namespace Volume
{
	float signNotZero(float value) {
		return value < 0.0 ? -1.0 : 1.0;
	};

	float toSNorm(float value, float rangeMaximum)
	{
		return round(
			(Math::Clamp(value, -1.0f, 1.0f) * 0.5 + 0.5) * rangeMaximum
		);
	}

	Vector2 octEncodeInRange(Vector3 normal, float rangeMax)
	{
		Vector2 result;
		result.x =
			normal.x / (fabs(normal.x) + fabs(normal.y) + fabs(normal.z));
		result.y =
			normal.y / (fabs(normal.x) + fabs(normal.y) + fabs(normal.z));

		if (normal.z < 0) {
			float x = result.x;
			float y = result.y;
			result.x = (1.0 - fabs(y)) * signNotZero(x);
			result.y = (1.0 - fabs(x)) * signNotZero(y);
		}

		result.x = toSNorm(result.x, rangeMax);
		result.y = toSNorm(result.y, rangeMax);

		return result;
	}

	Vector2 octEncode(Vector3 vector) {
		return octEncodeInRange(vector, 255);
	};

	Vector2 VolumeUtil::computeNormal(float value, float positiveX, float nagativeX, float positiveY, float nagativeY)
	{
		Vector2 nor(0.0f, 0.0f);
		float dx = (std::min)(positiveX, nagativeX) - value;
		float dy = (std::min)(positiveY, nagativeY) - value;

		if (dx != 0.0f || dy != 0.0f)
		{
			Vector3 normal(dx, dy, (std::max)(dx, dy));
			normal.normalise();
			nor = octEncode(normal);
		}
		return nor;
	}
}}